#include "study_widget_bottom.h"
#include "stydatabase.h"
#include "main_left_widget.h"

#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#include <QTime>
#include <QDate>
#include <QDateTime>

void get_stytime(qint64 *styTime);
qint64 styTime[TOTLE_TIME];
int styTimeMin=0;

study_widget_bottom::study_widget_bottom(QWidget *parent)
    : QWidget(parent)
    , m_isMousePressed(false)
    , m_isMouseMoved(false)
    , m_timeInterval(INTERVAL_DISTANCE)
    , m_currentMouseStepDistance(MOVE_STEP_DISTANCE)
    , m_currentScaleFactor (1)
    , m_isFirstSet(true)
    , m_centerX(0)
{
    m_adjustScaleAnimation = new QPropertyAnimation(this, "");
    m_adjustScaleAnimation->setDuration(ANIMATION_DURATION);
    m_adjustScaleAnimation->setEasingCurve(QEasingCurve::OutElastic);

    connect(m_adjustScaleAnimation,SIGNAL(valueChanged(QVariant)), this,SLOT(m_adjustScaleAnimationValueChanged(QVariant)));
    connect(m_adjustScaleAnimation,SIGNAL(finished()),this,SLOT(m_adjustScaleAnimationFinished()));

    get_stytime(styTime);
}
void get_stytime(qint64 *styTime)
{
    for(int i=0;i<TOTLE_TIME;i++){
        *(styTime+i)=0;
    }
    QSqlQuery query;
    QString queryString = QString("select PDay,PHour,PStyTime from %1 where PDay=\"%2-%3-%4\"").arg(
                g_data[0].friends.penName).arg(selectedDate.year()).arg(selectedDate.month()).arg(selectedDate.day());
    query.prepare(queryString);
    query.exec();
    while(query.next()){
        styTime[query.value(1).toInt()]=query.value(2).toLongLong();
        //qDebug()<<query.value(1).toInt()<<":"<<query.value(2).toLongLong();
    }
}
void study_widget_bottom::onStyStatusChanged(qint64 timestamp)
{
    qlonglong timeBit = 0;
    QDateTime today = QDateTime::fromTime_t(timestamp);
    if(today.date().year()<2019){
        qDebug()<<"时间不对";
        return ;
    }
    QSqlQuery query;
    QString queryString = QString("select PStyTime from %1 where PDay=\"%2\" AND PHour=%3").arg(g_data[0].friends.penName).arg(today.toString("yyyy-MM-dd")).arg(today.time().hour());
    qDebug()<<queryString;
    query.prepare(queryString);
    query.exec();
    if(query.lastError().isValid()){
        qDebug() << query.lastError().text();
        QSqlDatabase::database().rollback();//回滚数据库上的事务??
    }else{
        qDebug()<<"select success!";
    }
    if(query.next()){//如果已经存在就更新
        timeBit = query.value(0).toLongLong();
        if(timeBit & (1<<today.time().minute())){
            qDebug()<<"无需修改";
        }else{
            timeBit |= (1<<today.time().minute());
            queryString=QString("UPDATE %1 SET PStyTime = %2 where PDay=\"%3\" AND PHour = %4").arg(g_data[0].friends.penName).arg(timeBit).arg(today.toString("yyyy-MM-dd")).arg(today.time().hour());
            qDebug()<<queryString;
            query.prepare(queryString);
            query.exec();
            if(query.lastError().isValid()){
                qDebug() << query.lastError().text();
                QSqlDatabase::database().rollback();//回滚数据库上的事务??
            }else{
                qDebug()<<"update success!";
            }
            styTime[today.time().hour()]=timeBit;
        }
    }else{//不存在就加入
        timeBit |= (1<<today.time().minute());
        queryString=QString("insert into %1 values (\"%2\",%3,%4)").arg(g_data[0].friends.penName).arg(today.toString("yyyy-MM-dd")).arg(today.time().hour()).arg(timeBit);
        qDebug()<<queryString;
        query.prepare(queryString);
        query.exec();
        if(query.lastError().isValid()){
            qDebug() << query.lastError().text();
            QSqlDatabase::database().rollback();//回滚数据库上的事务??
        }else{
            qDebug()<<"insert success!";
        }
        styTime[today.time().hour()]=timeBit;
    }
    //paintEvent(NULL);
    resetTimeLine();
}

void study_widget_bottom::paintEvent(QPaintEvent *event)
{
    styTimeMin=0;
    QPainter painter(this);
    painter.fillRect(this->rect(), QColor(230, 230, 230));/*填充黑色背景*/

    /*中间那条竖线*/
    painter.setPen(QPen(QColor(37, 197, 220)));/*青色*/
    painter.drawLine(QLine(QPoint(m_centerX, 0), QPoint(m_centerX, this->height())));

    //绘制学习时间
    painter.setPen(QPen(QColor(82, 94, 84)));/*灰色*/
    for (int i = 0; i < TOTLE_TIME; i++)
    {
        styTimeMin+=drawStudyHour(&painter, i, styTime[i]);
    }

    // 绘制时间轴;
    painter.setPen(QPen(QColor(230, 60, 25)));/*红色*/
    painter.drawLine(QLine(QPoint(m_transformX, this->height()), QPoint(m_transformX, this->height() - HOUR_HEIGHT)));/*中间那根红线，从下到上*/
    painter.drawText(QPoint(m_transformX - 8, this->height() - HOUR_HEIGHT - 5), "00");/*数字 00*/

    for (int i = 1; i <= TOTLE_TIME; i++)
    {
        drawOneHour(&painter, i);
    }
    // 标明当前时间;
    if (m_adjustScaleAnimation->state() == QAbstractAnimation::Stopped)
    {
        m_strCurrentTime = QString("时间: %1").arg(getCurrentTime().toString("hh:mm:ss"));
    }
    painter.drawText(QPoint(this->width()*0.9, 20), m_strCurrentTime);
    // 绘制当前缩放倍率;
    QString strScaleFactor = QString("缩放因子: %1").arg(m_currentScaleFactor);
    painter.drawText(QPoint(this->width()*0.9, 40), strScaleFactor);
    //学习总时长 styTimeMin
    painter.setPen(QPen(QColor(82, 94, 84)));/*青色*/
    painter.setFont(QFont("Helvetica [Cronyx]",12,QFont::ExtraBold));
    QString strstyTimeMin = QString("学习总时长: %1%2%3%4").arg(styTimeMin/60).arg(" 小时 ").arg(styTimeMin%60).arg(" 分钟");
    painter.drawText(QPoint(10, 20), strstyTimeMin);
}

void study_widget_bottom::resizeEvent(QResizeEvent *event)
{
    //qDebug()<<"resizeEvent";
    if (m_isFirstSet)
    {
        m_isFirstSet = false;
        m_centerX = this->width() / 2;
        m_transformX = m_centerX;
        m_transformBeforeX = m_centerX;
    }
    else
    {
        int disTance = this->width() / 2 - m_centerX;
        m_centerX = this->width() / 2;
        m_transformX += disTance;
        m_transformBeforeX = m_transformX;
    }
}

void study_widget_bottom::adjustCurrentScale()
{
    //qDebug()<<"adjustCurrentScale";
    QTime currentTime = getCurrentTime();
    int currentSecond = QTime(0, 0, 0).secsTo(currentTime);
    int timeDistance = m_centerX - m_transformX;
    if (currentTime.secsTo(QTime(0, 0, 0)) == 0 && timeDistance > 0)
    {
        // 说明是24h，因为QTime在时间为24:00:00时自动转为00:00:00;
        currentSecond = TOTLE_TIME * 60 * 60;
    }

    // 计算放缩之后的距离差;
    int timeDistanceBefore =  1.0 * currentSecond / 60 / 60 * 10 * m_timeInterval;

    m_timeInterval = INTERVAL_DISTANCE * m_currentScaleFactor;
    m_currentMouseStepDistance = MOVE_STEP_DISTANCE * m_currentScaleFactor;

    int timeDistanceAfter = 1.0 * currentSecond / 60 / 60 * 10 * m_timeInterval;
    int adjustTransformX = m_transformX + timeDistanceBefore - timeDistanceAfter;

    // 如果是零点则直接放缩，不需动画效果;
    if (currentSecond == 0)
    {
        m_transformX = adjustTransformX;
        update();
    }
    else
    {
        // 动画移动到对应的点;
        m_adjustScaleAnimation->setStartValue(m_transformX);
        m_adjustScaleAnimation->setEndValue(adjustTransformX);
        m_adjustScaleAnimation->start();
    }
}

void study_widget_bottom::setScaleSmall()
{
    if (m_adjustScaleAnimation->state() == QAbstractAnimation::Running)
    {
        return;
    }

    if (m_currentScaleFactor-- == MIN_SCALE_FACTOR)
    {
        m_currentScaleFactor = MIN_SCALE_FACTOR;
    }
    adjustCurrentScale();
}

void study_widget_bottom::setScaleBig()
{
    if (m_adjustScaleAnimation->state() == QAbstractAnimation::Running)
    {
        return;
    }

    if (++m_currentScaleFactor > MAX_SCALE_FACTOR)
    {
        m_currentScaleFactor = MAX_SCALE_FACTOR;
    }
    adjustCurrentScale();
}

void study_widget_bottom::resetTimeLine()
{
    m_currentScaleFactor = MIN_SCALE_FACTOR;
    m_timeInterval = INTERVAL_DISTANCE * m_currentScaleFactor;
    m_currentMouseStepDistance = MOVE_STEP_DISTANCE * m_currentScaleFactor;
    m_transformX = m_transformBeforeX = m_centerX;
    update();
}

QTime study_widget_bottom::getCurrentTime()
{
    int timeDistance = m_centerX - m_transformX;
    int second = 1.0 * timeDistance / 10 / m_timeInterval * 60 * 60;
    QTime currentTime = QTime(0, 0, 0).addSecs(second);
    return currentTime;
}

QString study_widget_bottom::getCurrentStrTime()
{
    return m_strCurrentTime;
}
/**
 * @brief study_widget_bottom::drawOneHour
 * @param painter
 * @param hour
 */
void study_widget_bottom::drawOneHour(QPainter *painter, int hour)
{
    int hourDistance = (hour - 1) * 10 * m_timeInterval;
    int startPosX = m_transformX + hourDistance;
    int i = 1;
    for (; i < 10; i++)
    {
        int minuteStartPosX = startPosX + i * m_timeInterval;
        painter->drawLine(QLine(QPoint(minuteStartPosX, this->height()), QPoint(minuteStartPosX, this->height() - MINUTE_HEIGHT)));
    }

    painter->drawLine(QLine(QPoint(startPosX + i * m_timeInterval, this->height()), QPoint(startPosX + i * m_timeInterval, this->height() - HOUR_HEIGHT)));
    QString strHour = QString::number(hour);
    hour < 10 ? strHour.prepend("0") : strHour;
    painter->drawText(QPoint(startPosX + i * m_timeInterval - 8, this->height() - HOUR_HEIGHT - 5), strHour);
}

int study_widget_bottom::drawStudyHour(QPainter *painter, int hour, qint64 time_bit)
{
    int min=0;
    if(time_bit==0)return 0;
    //else qDebug()<<hour<<":"<<time_bit;
    int hourDistance = hour * 10 * m_timeInterval;

    int startPosX = m_transformX + hourDistance;
    for(int i=0;i<60;i++){
        int twoMinStartPosX = startPosX + i * m_timeInterval/6;//每个小矩形跨度2分钟
        if((time_bit>>i)&0x01){
            painter->fillRect(QRect(QPoint(twoMinStartPosX,this->height()),//topleft
                QPoint(twoMinStartPosX+m_timeInterval/6,this->height()*0.4)),//buttomright
                QColor(82, 94, 84));
            min++;
        }
    }
    return min;
}

void study_widget_bottom::mouseMoveEvent(QMouseEvent *event)
{
    if (m_adjustScaleAnimation->state() == QAbstractAnimation::Running)
    {
        return;
    }

    if (m_isMousePressed)
    {
        m_isMouseMoved = true;
        QPoint movePoint = event->pos();
        int distance = movePoint.x() - m_pressPoint.x();
        m_transformX = m_transformBeforeX + distance;

        int maxDistance = TOTLE_TIME * 10 * m_timeInterval - m_centerX;
        if (distance > 0 && m_transformX > m_centerX)
        {
            m_transformX = m_centerX;
        }
        else if (distance < 0 && m_transformX < (-maxDistance))
        {
            m_transformX = -maxDistance;
        }
        update();
    }
}

void study_widget_bottom::mousePressEvent(QMouseEvent *event)
{
    //qDebug()<<"mousePressEvent";
    if (m_adjustScaleAnimation->state() == QAbstractAnimation::Running)
    {
        return;
    }

    m_isMousePressed = true;
    m_pressPoint = event->pos();
}

void study_widget_bottom::mouseReleaseEvent(QMouseEvent *event)
{
    //qDebug()<<"mouseReleaseEvent";
    if (m_adjustScaleAnimation->state() == QAbstractAnimation::Running)
    {
        return;
    }

    if (m_isMouseMoved)
    {
        m_isMouseMoved = false;
    }
    else if(m_isMousePressed)
    {
        QPoint releasePoint = event->pos();
        int mousePressTransformX;
        if (releasePoint.x() > this->width() / 2)
        {
            int maxDistance = TOTLE_TIME * 10 * m_timeInterval - m_centerX;
            int currentMouseStepDistance = releasePoint.x() - m_centerX;
            mousePressTransformX = m_transformX - currentMouseStepDistance;
            if (mousePressTransformX < (-maxDistance))
            {
                mousePressTransformX = -maxDistance;
            }
        }
        else
        {
            int currentMouseStepDistance = releasePoint.x() - m_centerX;
            mousePressTransformX = m_transformX - currentMouseStepDistance;
            if (mousePressTransformX > m_centerX)
            {
                mousePressTransformX = m_centerX;
            }
        }
        m_adjustScaleAnimation->setStartValue(m_transformX);
        m_adjustScaleAnimation->setEndValue(mousePressTransformX);
        m_adjustScaleAnimation->start();
    }

    m_isMousePressed = false;
    m_transformBeforeX = m_transformX;
}

void study_widget_bottom::m_adjustScaleAnimationValueChanged(const QVariant &value)
{
    m_transformX = value.toInt();
    update();
}

void study_widget_bottom::m_adjustScaleAnimationFinished()
{
    m_transformBeforeX = m_transformX;
    update();
}

void study_widget_bottom::updateSelectedDate()
{
    get_stytime(styTime);
    this->paintEvent(NULL);
    resetTimeLine();
}



